home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
oper_sys
/
oasis
/
oasis1-1.lha
/
oasis-1.1
/
gen.y
< prev
next >
Wrap
Text File
|
1992-05-01
|
45KB
|
740 lines
/*==========================================================================*
Oasis Alpha Version 1.1 (C) Copyright 1992 Fah-Chun Cheong
Revised: 5/1/92 by: fcc@eecs.umich.edu and The University of Michigan
------------------------------------------------------------------------
Permission to use, copy, modify, distribute, sell and resell Oasis Alpha
software and its documentation for any purpose and without fee is hereby
granted, provided that the authorship be appropriately credited and
acknowledged, and that the above copyright notice appear in all copies
and both the copyright notice and this permission notice appear in
supporting documentation. The author makes no representations about the
suitability of this software for any purpose. It is provided "as is"
without express or implied warranty. Oasis Alpha is free, caveat emptor!
------------------------------------------------------------------------
To request Oasis Alpha source code: oasis-alpha-request@eecs.umich.edu
To enroll in the mailing list: oasis-alpha-request@eecs.umich.edu
To send bug reports: oasis-alpha-bugs@eecs.umich.edu
To discuss openly all matters Oasis: oasis-alpha@eecs.umich.edu
*==========================================================================*/
%{
#include "gener.h"
#define PNO 5000
char *buf;
Program *ptab;
int pno = 0;
int pix = 0;
static int fail, next, skip, labno = 0;
static int a;
static int b;
static int n;
static int k;
static int s;
static char lab[1024];
static char *pname;
static int failed;
%}
%union {
int i;
double f;
char c;
char *s;
}
%token DOT DO ISA IF THEN RETURN
%token EQ NE LT LE GT GE
%token C I F O A Y L
%token NIL TRUE FAIL WAIT POST
%token <s> ID CID
%token <i> G VID MID GID LID
%token <i> ATINET
%token <i> INTEGER
%token <f> FLOAT
%token <c> CHARACTER
%token <s> STRING
%type <i> header
%type <s> class
%type <i> variables0
%type <i> pointers0
%type <i> pointers
%type <i> metas0
%type <i> metas
%type <i> args0
%type <i> args
%type <i> literal
%type <i> integer
%type <i> float
%type <i> indices
%type <i> location
%type <i> accessors
%type <i> l1
%type <i> l2
%type <i> l3
%type <i> l4
%type <i> l1_
%type <i> l2_
%type <i> l3_
%%
start : DO { emit0 (".text");
entry ("main"); }
main {}
| programs {}
;
programs : programs program {}
| program {}
;
program : header ':' INTEGER ':' INTEGER { pix = put(pname, $1, $5);
emit0 (".data");
emit0 (".align");
labelC(pix);
if (isupper(*pname)) {
emit0c(".word", 1);
emit0c(".word", 2);
emit0c(".word", 3);
}}
genes0 '{' data0 '}' { emit0 (".text"); }
'{' goal0 procedures0 '}' { pix = 0; }
;
header : CID ISA CID { pname = $3; $$ = get($1); }
| ID ISA ID { pname = $3; $$ = get($1); }
| CID { pname = $1; $$ = 0; }
| ID { pname = $1; $$ = 0; }
;
genes0 : LT genes GT {}
| empty {}
;
genes : genes ',' gene {}
| gene {}
;
gene : GID { emit0c(".word", $1); }
;
data0 : atoms0 ';' { emit0c(".word", -1); }
molecules0 ';' { emit0c(".word", -1); }
polymorphs0 { emit0c(".word", -1); }
;
atoms0 : atoms {}
| empty {}
;
atoms : atoms ',' atom {}
| atom {}
;
atom : GID w { emit0c(".word", $1); }
;
molecules0 : molecules {}
| empty {}
;
molecules : molecules ',' molecule {}
| molecule {}
;
molecule : GID p { emit0c(".word", $1); }
;
polymorphs0 : polymorphs {}
| empty {}
;
polymorphs : polymorphs ',' polymorph {}
| polymorph {}
;
polymorph : GID G { emit0c(".word", $1);
emit0c(".word", $2); }
;
goal0 : goal {}
| empty {}
;
goal : DO { labelL(pix, 0);
fill (pix, 0); }
main {}
;
main : INTEGER { skip = fail = gen(1);
failed = FALSE;
emit2 ("entr", k = 1, s = $1+1); }
body '.' { emit0 ("done");
emit1 ("exit", s);
if (failed) {
label (fail);
emit0 ("quit");
emit1 ("exit", s);
}}
;
procedures0 : procedures {}
| empty {}
;
procedures : procedures procedure {}
| procedure {}
;
procedure : rules '.' { if (failed) {
label (fail);
emit2 ("fail", k, s);
}}
;
rules : rules ';' { label (next); }
mark0 rule {}
| prolog check0 mark0 rule {}
;
prolog : MID ':' INTEGER ':' INTEGER ':' INTEGER { labelL(pix, $1);
fill (pix, $1);
fail = gen(1);
failed = FALSE;
k = $3 < $5 ? $5+1 : $3+1;
emit2 ("entr", k, s = $7+1); }
;
check0 : { emit0_("chek", skip = gen(1));
emit0_("coll", gen(1));
emit0 (".data");
label (gen(0)); }
'[' variables0 ']' { emit0 (".text");
label (skip); }
| empty {}
;
mark0 : ';' { skip = next = fail; }
| empty { skip = next = gen(1); }
;
rule : { a = s; n = 0; }
'(' inputs0 ')' clause0 RETURN result0 {}
;
clause0 : IF body then body {}
| IF body {}
| then body {}
| empty {}
;
then : THEN { skip = fail; }
;
body : body ';' messages {}
| messages {}
;
messages : mess ',' messages sage { failed = memo(skip, fail); }
| mess sage { failed = memo(skip, fail); }
| message { failed = memo(skip, fail); }
| primitive {}
;
mess : MID '[' args0 ']' '(' parameters0 ')'
'[' args0 ']' { emit1c("lodc", ++n, $9);
emit1c("lodc", ++n, $3);
emit1c("lodc", ++n, $1); }
'!' remote { emit1 ("send", n); }
;
sage : ':' INTEGER { emit1_("recv", n = $2, skip); }
'(' outputs0 ')' {}
;
message : MID ':' INTEGER ':' INTEGER { n = $3 < $5 ? $5-$3 : 0; }
'(' parameters0 ')' target { emit0_(".addr", gen(1));
emit0_(".addr", skip); }
'[' variables0 ']' { label (gen(0));
n = $5; }
'(' outputs0 ')' {}
;
target : '!' local { emit3 ("invk", n, $<i>-4, $<i>-8); }
| class { emit2 ("lods", ++n, s);
emit2L("call", n, $<i>-4, Lab($1, $<i>-8)); }
;
result0 : MID '(' parameters0 ')' class { emit3L("jump", k, s, n, Lab($5, $1)); }
| check0 '(' parameters0 ')' { emit3 ("retr", k, s, n); }
| check0 '(' parameters0 ')' '*' { emit3 ("rets", k, s, n); }
| empty {}
;
remote : location A { emit3 ("lodm", n, n, $1); }
| LID A { emit2 ("lods", ++n, s+$1); }
| handle {}
;
local : location O { emit3 ("lodm", n, n, $1); }
| LID O { emit2 ("lods", ++n, s+$1); }
;
class : ISA CID { $$ = $2; }
| ISA ID { $$ = $2; }
| empty { $$ = pname; }
;
primitive : equality { failed = memo(skip, fail); }
| inequality { failed = memo(skip, fail); }
| matching {}
| synchrony {}
| TRUE {}
| FAIL { emit0_("bran", skip);
failed = memo(skip, fail); }
;
equality : parameter EQ expression { emit2_("bner", n-1, n, skip); n-=2; }
| parameter NE expression { emit2_("beqr", n-1, n, skip); n-=2; }
| parameter EQ location x { emit3_("bnem", n-1, n, $3, skip); n-=2; }
| parameter NE location x { emit3_("beqm", n-1, n, $3, skip); n-=2; }
| parameter EQ LID x { emit2_("bnes", n--, s+$3, skip); }
| parameter NE LID x { emit2_("beqs", n--, s+$3, skip); }
| parameter EQ nil { emit1_("bnez", n--, skip); }
| parameter NE nil { emit1_("beqz", n--, skip); }
| parameter EQ literal { if ($3) emitc_("bnec", n--, $3, skip);
else emit1_("bnez", n--, skip); }
| parameter NE literal { if ($3) emitc_("beqc", n--, $3, skip);
else emit1_("beqz", n--, skip); }
;
inequality : express I LT express I { emit1_("bge.i", n--, skip); n--; }
| express I LE express I { emit1_("bgt.i", n--, skip); n--; }
| express I GT express I { emit1_("ble.i", n--, skip); n--; }
| express I GE express I { emit1_("blt.i", n--, skip); n--; }
| express F LT express F { emit1_("bge.f", n--, skip); n--; }
| express F LE express F { emit1_("bgt.f", n--, skip); n--; }
| express F GT express F { emit1_("ble.f", n--, skip); n--; }
| express F GE express F { emit1_("blt.f", n--, skip); n--; }
;
matching : parameter '=' pattern0_as { n--; }
| parameter '=' '_' { n--; }
;
synchrony : POST '(' parameter ')' '!' VID { emit2 ("post", n--, $6); }
| WAIT '(' parameter ')' '!' VID { emit2_("wait", n--, $6, gen(1)); }
'[' variables0 ']' { emit0c(".word", $9 + 3);
label (gen(0)); }
;
variables0 : pointers0 ';' { emit0c(".word", -s); }
metas0 { emit0c(".word", -s-k);
$$ = $1 + $4; }
;
pointers0 : pointers { $$ = $1; }
| empty { $$ = 0; }
;
pointers : pointers ',' pointer { $$ = $1 + 1; }
| pointer { $$ = 1; }
;
pointer : LID p { emit0c(".word", s+$1); }
;
metas0 : metas { $$ = $1; }
| empty { $$ = 0; }
;
metas : metas ',' meta { $$ = $1 + 2; }
| meta { $$ = 2; }
;
meta : LID G { emit0c(".word", s+$1);
emit0c(".word", $2); }
;
x : w {}
| p {}
| G {}
;
w : C {}
| I {}
| F {}
;
p : O {}
| A {}
| Y {}
| L {}
;
args0 : args { $$ = $1; }
| empty { $$ = 0; }
;
args : args ',' arg { $$ = $1 + 1; }
| arg { $$ = 1; }
;
arg : C { emit1c("lodc", ++n, T_CHAR); }
| I { emit1c("lodc", ++n, T_INT); }
| F { emit1c("lodc", ++n, T_FLOAT); }
| p { emit1c("lodc", ++n, T_POINTER); }
| G { emit2 ("lods", ++n, s);
emit3 ("lodm", n, n, $1); }
;
parameters0 : parameters {}
| empty {}
;
parameters : parameters ',' parameter {}
| parameter {}
;
parameter : instance {}
| expression {}
| location x { emit3 ("lodm", n, n, $1); }
| LID x { emit2 ("lods", ++n, s+$1); }
| nil { emit1 ("lodz", ++n); }
| literal { if ($1) emit1c("lodc", ++n, $1);
else emit1 ("lodz", ++n); }
;
value : instance { emit3 ("stor", n-1, ++b, n); n--; }
| expression { emit3 ("stor", n-1, ++b, n); n--; }
| location x { emit4 ("stom", n-1, ++b, n, $1); n--; }
| LID x { emit3 ("stos", n, ++b, s+$1); }
| nil { emit2 ("stoz", n, ++b); }
| literal { if ($1) emit2c("stoc", n, ++b, $1);
else emit2 ("stoz", n, ++b); }
;
instance : list {}
| array {}
| string {}
| handle {}
| agent {}
| object {}
;
list : l2 elements '|' location L ']' { emit4 ("stom", n-1, ++b, n, $4); b = $1; n--; }
| l2 elements '|' LID L ']' { emit3 ("stos", n, ++b, s+$4); b = $1; }
| l2 elements ']' { emit2 ("stoz", n, ++b); b = $1; }
;
l2 : INTEGER { emit2 ("brek", ++n, $1*3); }
elem_t '[' { $$ = b; b = 0; }
;
elem_t : C { emit2c("stoc", n, 0, HEADER(I_LISTC, 3)); }
| I { emit2c("stoc", n, 0, HEADER(I_LISTI, 3)); }
| F { emit2c("stoc", n, 0, HEADER(I_LISTF, 3)); }
| p { emit2c("stoc", n, 0, HEADER(I_LISTP, 3)); }
| G { emit2 ("lods", n+1, s);
emit4 ("stom", n, 0, n+1, $1); }
;
elements : elements ',' { emit2 ("cdra", n, ++b);
emit4 ("stom", n, ++b, n, 0); }
element {}
| element {}
;
element : value {}
;
array : l3 '[' sizes ']' '{' items '}' { b = $1; }
| l3 '[' sizes ']' { b = $1; }
;
string : STRING { int i, j = strlen($1);
emit2 ("brek", ++n, 3+j);
emit2c("stoc", n, 0, HEADER(I_ARRAYC, 3+j));
emit2c("stoc", n, 1, 1);
if (j) emit2c("stoc", n, 2, j);
else emit2 ("stoz", n, 2);
for (i = 0; i < j; i++)
emit2c("stoc", n, i+3, $1[i]); }
;
l3 : INTEGER ':' INTEGER { emit2 ("brek", ++n, 2+$1+$3);
emit2 ("zero", n, 2+$1+$3);
$<i>$ = 2+$1+$3; }
item_t '$' { emit2c("stoc", n, 1, $1);
$$ = b; b = 1; }
;
item_t : C { emit2c("stoc", n, 0, HEADER(I_ARRAYC, $<i>0)); }
| I { emit2c("stoc", n, 0, HEADER(I_ARRAYI, $<i>0)); }
| F { emit2c("stoc", n, 0, HEADER(I_ARRAYF, $<i>0)); }
| p { emit2c("stoc", n, 0, HEADER(I_ARRAYP, $<i>0)); }
| G { emit2 ("lods", n+1, s);
emit3 ("lodm.i", n+1, n+1, $1);
emit1c("lodc.i", n+2, OFFSET($<i>0));
emit1 ("add.i", n+2);
emit1 ("itow", n+1);
emit3 ("stor", n, 0, n+1); }
;
sizes : sizes ',' size {}
| size {}
;
size : value {}
;
items : items ',' item {}
| item {}
;
item : value {}
;
handle : CID ':' INTEGER ATINET ':' INTEGER { emit2 ("brek", ++n, 4);
emit2c("stoc", n, 0, HEADER(I_HANDLE, 4));
emit2c("stoc", n, 1, HEADER(get($1), $3));
if ($4) emit2c("stoc", n, 2, $4);
else emit2 ("stoz", n, 2);
if ($6) emit2c("stoc", n, 3, $6);
else emit2 ("stoz", n, 3); }
;
agent : l4 types0 '{' properties0 '}'
ATINET ':' INTEGER { if ($6) emit2c("stoc", n, 2, $6);
else emit2 ("stoz", n, 2);
if ($8) emit2c("stoc", n, 3, $8);
else emit2 ("stoz", n, 3);
emit1 ("cret", n);
b = $1; }
;
l4 : CID ':' INTEGER { emit2 ("brek", ++n, $3);
emit2c("stoc", n, 0, HEADER(get($1), $3));
emit2c("stoc", n, 1, HEADER(get($1), $3));
$$ = b; b = 3; }
;
object : l1 types0 '{' properties0 '}' { b = $1; }
;
l1 : ID ':' INTEGER { emit2 ("brek", ++n, $3);
emit2c("stoc", n, 0, HEADER(get($1), $3));
$$ = b; b = 0; }
;
types0 : '[' types ']' {}
| empty {}
;
types : types ',' type {}
| type {}
;
type : C { emit2c("stoc", n, ++b, T_CHAR); }
| I { emit2c("stoc", n, ++b, T_INT); }
| F { emit2c("stoc", n, ++b, T_FLOAT); }
| p { emit2c("stoc", n, ++b, T_POINTER); }
| G { emit2 ("lods", n+1, s);
emit4 ("stom", n, ++b, n+1, $1); }
;
properties0 : properties {}
| empty {}
;
properties : properties ',' property {}
| property {}
;
property : value {}
;
location : GID { emit2 ("lods", ++n, s);
emit3 ("lodm", n, n, $1); }
accessors { $$ = $3; }
| LID { emit2 ("lods", ++n, s+$1); }
accessors { $$ = $3; }
| GID { emit2 ("lods", ++n, s);
$$ = $1; }
;
accessors : accessor accessors { $$ = $2; }
| DOT GID { $$ = $2; }
| '[' indices ']' { $$ = $2+2;
emit1 ("indx", n--); }
;
accessor : DOT GID { emit3 ("lodm", n, n, $2); }
| '[' indices ']' { emit1 ("indx", n--);
emit3 ("lodm", n, n, $2+2); }
;
indices : indices ',' { emit3 ("lodm.i", n+1, n-1, $1+2);
emit1 ("mul.i", n+1); }
index { emit1 ("add.i", n--);
$$ = $1 + 1; }
| index { $$ = 1; }
;
index : express I {}
;
expression : express I { emit1 ("itow", n); }
| express F { emit1 ("ftow", n); }
;
express : '(' expr ')' {}
;
expr : expr '-' '\'' F term { emit1 ("subr.f", n--); }
| expr '-' '\'' I term { emit1 ("subr.i", n--); }
| expr '+' F term { emit1 ("add.f", n--); }
| expr '-' F term { emit1 ("sub.f", n--); }
| expr '+' I term { emit1 ("add.i", n--); }
| expr '-' I term { emit1 ("sub.i", n--); }
| '-' F factor { emit1 ("neg.f", n); }
| '-' I factor { emit1 ("neg.i", n); }
| term {}
;
term : term '/' '\'' F factor { emit1 ("divr.f", n--); }
| term '%' '\'' F factor { emit1 ("remr.f", n--); }
| term '/' '\'' I factor { emit1 ("divr.i", n--); }
| term '%' '\'' I factor { emit1 ("remr.i", n--); }
| term '*' F factor { emit1 ("mul.f", n--); }
| term '/' F factor { emit1 ("div.f", n--); }
| term '%' F factor { emit1 ("rem.f", n--); }
| term '*' I factor { emit1 ("mul.i", n--); }
| term '/' I factor { emit1 ("div.i", n--); }
| term '%' I factor { emit1 ("rem.i", n--); }
| factor {}
;
factor : express {}
| ID express { emit1 ($1, n); }
| location I { emit3 ("lodm.i", n, n, $1); }
| location F { emit3 ("lodm.f", n, n, $1); }
| LID I { emit2 ("lods.i", ++n, s+$1); }
| LID F { emit2 ("lods.f", ++n, s+$1); }
| integer { if ($1) emit1c("lodc.i", ++n, $1);
else emit1 ("lodz.i", ++n); }
| float { if ($1) emit1c("lodc.f", ++n, $1);
else emit1 ("lodz.f", ++n); }
;
literal : integer { $$ = $1; }
| float { $$ = $1; }
| CHARACTER { $$ = $1; }
;
integer : '-' INTEGER { $$ = -$2; }
| INTEGER { $$ = $1; }
;
float : '-' FLOAT { $$ = ftow(-$2); }
| FLOAT { $$ = ftow($1); }
;
nil : NIL {}
| '[' ']' {}
;
outputs0 : outputs {}
| empty {}
;
outputs : outputs ',' output {}
| output {}
;
output : pattern0_as { n--; }
| '_' { n--; }
;
inputs0 : inputs {}
| empty {}
;
inputs : inputs ',' input {}
| input {}
;
input : { emit2 ("lods", ++n, ++a); }
pattern0_as { n--; }
| '_' { ++a; }
;
value_ : { emit3 ("lodm", n+1, n, ++a); ++n; }
pattern0_as { n--; }
| '_' { ++a; }
;
pattern0_as : pattern0_ '?' location x { emit3 ("stor", n, $3, n-1); n--; }
| pattern0_ '?' LID x { emit2 ("move", n, s+$3); }
| pattern_ { failed = memo(skip, fail); }
;
pattern0_ : pattern_ { failed = memo(skip, fail); }
| empty {}
;
pattern_ : instance_ {}
| expression_ {}
| reference_ {}
| literal_ {}
| nil_ {}
;
instance_ : list_ {}
| array_ {}
| string_ {}
| handle_ {}
| object_ {}
;
list_ : l2_ elements_ '|' { a = 1; }
value_ ']' { a = $1; n--; }
| l2_ elements_ ']' { emit3 ("lodm", n, n, ++a); a = $1;
emit1_("bnez", n--, skip); }
;
l2_ : '[' { emit1_("beqz", n, skip);
emit2 ("lodr", n+1, n);
$$ = a; a = 0; ++n; }
;
elements_ : elements_ ',' { emit3 ("lodm", n, n, ++a); a = 0;
emit1_("beqz", n, skip); }
element_ {}
| element_ {}
;
element_ : value_ {}
;
array_ : l3_ '[' sizes_ ']' '{' items_ '}' { a = $1; }
| l3_ '[' sizes_ ']' { a = $1; }
;
string_ : STRING { int i, j = strlen($1);
emit1_("beqz", n, skip);
emit3 ("lodm", n+1, n, 2);
if (j) emitc_("bnec", n+1, j, skip);
else emit1_("bnez", n+1, skip);
for (i = 0; i < j; i++) {
emit3 ("lodm", n+1, n, i+3);
emitc_("bnec", n+1, $1[i], skip);
}}
;
l3_ : '$' { emit1_("beqz", n, skip);
$$ = a; a = 1; }
;
sizes_ : sizes_ ',' size_ {}
| size_ {}
;
size_ : value_ {}
;
items_ : items_ ',' item_ {}
| item_ {}
;
item_ : value_ {}
;
handle_ : CID ':' INTEGER ATINET ':' INTEGER { emit1_("beqz", n, skip);
emit3 ("lodm", n+1, n, 1);
emitc_("bnec", n+1, HEADER(get($1), $3), skip);
emit3 ("lodm", n+1, n, 2);
if ($4) emitc_("bnec", n+1, $4, skip);
else emit1_("bnez", n+1, skip);
emit3 ("lodm", n+1, n, 3);
if ($6) emitc_("bnec", n+1, $6, skip);
else emit1_("bnez", n+1, skip); }
;
object_ : l1_ types0_ '{' properties0_ '}' { a = $1; }
;
l1_ : ID ':' INTEGER { emit1_("beqz", n, skip);
emit3 ("lodm", n+1, n, 0);
emitc_("bnec", n+1, HEADER(get($1), $3), skip);
$$ = a; a = 0; }
;
types0_ : '[' types_ ']' {}
| empty {}
;
types_ : types_ ',' type_ {}
| type_ {}
;
type_ : x { ++a; }
;
properties0_ : properties_ {}
| empty {}
;
properties_ : properties_ ',' property_ {}
| property_ {}
;
property_ : value_ {}
;
expression_ : expression { emit2_("bner", n-1, n, skip); n--; }
;
reference_ : location x { emit3_("bnem", n-1, n, $1, skip); n--; }
| LID x { emit2_("bnes", n, s+$1, skip); }
;
literal_ : literal { if ($1) emitc_("bnec", n, $1, skip);
else emit1_("bnez", n, skip); }
;
nil_ : nil { emit1_("bnez", n, skip); }
;
empty : {}
;
%%
int get(id)
char *id;
{
int i;
for (i = 0; i < pno; i++)
if (!strcmp(ptab[i].name, id))
return i;
#ifdef SHELL
err1("Unimplemented class `%s'.\n", id);
exit(0);
#endif
ptab[pno].name = new(id);
ptab[pno].isa = 0;
ptab[pno].mno = -1;
ptab[pno].mtab = NUL;
return pno++;
}
int put(id, isa, mno)
char *id;
int isa;
int mno;
{
int i = get(id);
if (ptab[i].mno == -1) {
ptab[i].mno = mno;
ptab[i].isa = isa;
ptab[i].mtab = newz(mno);
return i;
}
if (ptab[i].mno > 1) {
err1("Duplicate program `%s' ignored.\n", id);
return -1;
}
return -1;
}
void fill(i, j)
int i;
int j;
{
if (i != -1) ptab[i].mtab[j] = i;
}
void init_gen(sno, stab)
int sno;
char *stab[];
{
int i;
ptab = (Program *) calloc(PNO, sizeof(Program));
for (i = 0; i < sno; i++)
put(stab[i], 0, 0);
}
void generate(pbuf, tbuf)
char *pbuf;
char *tbuf;
{
buf = tbuf;
init_scan(pbuf);
zzparse();
}